package com.phonetools.commonutils.security

import java.io.ByteArrayOutputStream
import java.security.PrivateKey
import java.security.PublicKey
import javax.crypto.Cipher

/**
 * 非对称加密
 */

/*fun main{
    val publicKeyStr =
        "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDymOuE7z9SfGv3Czq1ZAwzukNknR1iVTBZurJ6BTh9cBiQUczZ9U4HgBtgIWMRaLNeFjkFMszQz/uDmWQXMJbcsYuSAEJNxUn5KuHAp2YEWfV2CXTj/3I/Q9rhGVq+aLs0rgfCvVXoxFjJV+uGPtzXxhVZTahCcwUo20MSPqI0WwIDAQAB"
    val privateKeyStr =
        "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAPKY64TvP1J8a/cLOrVkDDO6Q2SdHWJVMFm6snoFOH1wGJBRzNn1TgeAG2AhYxFos14WOQUyzNDP+4OZZBcwltyxi5IAQk3FSfkq4cCnZgRZ9XYJdOP/cj9D2uEZWr5ouzSuB8K9VejEWMlX64Y+3NfGFVlNqEJzBSjbQxI+ojRbAgMBAAECgYAT4bpzk5Px86Z5gZ8XHJLvblV1mna9B1RGFknoPCNMDHLG6R1Lw5HYhYQ41aOj2pvQmyujJG2qs1DekSSlzeKfHMgoiHiKO/LPLCe4QgbkCsxtTy+SloVM/EirMBCwoPjMwYPqoxVm1a38kCqNgiitMpGooTXflCR0jgGvR9ej+QJBAPwTrCkk6SupWERxQG7yBdCIO9lyWzer9DPa2+JmMcoNydov4bq2ZUCgpum8JkAkmhonM1Oz8x6OFOwcbzHnyZ0CQQD2X3qpvF1Iyc3M/gqZcOSTORQTRkZVSt5ctPnJw6lIGax+HMr9YNccuiwlfi2UtSA0NOtC5yozDS8s9Xt2yHBXAkAzfKkrdjiSDHLU9/TbNF/vqgPfdDYhduPYO5mx8oG07YAPKryGcH7Z5nZxQ1bkvxUixmL7c8Pyt76aQ2yK2vcZAkBLoDFR6t0jm7aNhymPwiSXwHyWEgtC4TFyeab3NRVAaYkWSRZSQqilS8yDUcECFbsl61yP889zTke94Die1JYPAkEAjy3tzsbUeVCMF5CTfAklXSoJbJMZiWvW0S5lolAV9TOVmXFsW+itONAivg7k6HYkxGQF78u6JdcCf5y5p1DqSQ=="

    val rsaContent = "RSA加密 RSA加密RSA加密"

    val encryptByPrivsteKey = encryptByPrivsteKey(rsaContent, privateKeyStr.genRSAPrivateKey())
    Log.d(TAG, "encryptByPrivsteKey=$encryptByPrivsteKey")
    val encryptByPublicKey = encryptByPublicKey(rsaContent, publicKeyStr.genRSAPublicKey())
    Log.d(TAG, "encryptByPublicKey=$encryptByPublicKey")
    val decryptByPrivsteKey =
        decryptByPrivsteKey(encryptByPublicKey, privateKeyStr.genRSAPrivateKey())
    Log.d(TAG, "decryptByPrivsteKey=$decryptByPrivsteKey")
    val decryptByPublicKey =
        decryptByPublicKey(encryptByPrivsteKey, publicKeyStr.genRSAPublicKey())
    Log.d(TAG, "decryptByPublicKey=$decryptByPublicKey")
}*/

val transformation = "RSA"
val ENCRYPT_MAX_SIZE = 117//加密不能超过117
val DECRYPT_MAX_SIZE = 128//解密不能超过128

/**
 * 私钥加密
 * @param content 需要加密的内容
 * @param privateKey 私钥
 * @return String
 */
fun encryptByPrivsteKey(content: String, privateKey: PrivateKey): String {

    val byteArray = content.toByteArray()

    //创建cipher
    val cipher = Cipher.getInstance(transformation)
    //初始化cipher
    cipher.init(Cipher.ENCRYPT_MODE, privateKey)
    //加密解密  分段加密
    //val encrypt = cipher.doFinal(input.toByteArray())
    var temp: ByteArray? = null
    var offset = 0//当前偏移位置
    val bos = ByteArrayOutputStream()
    while (byteArray.size - offset > 0) {//没加密完
        //每次最大加密117个字节
        if (byteArray.size - offset >= ENCRYPT_MAX_SIZE) {
            //剩余部分大于117
            //加密完整的117字节
            temp = cipher.doFinal(byteArray, offset, ENCRYPT_MAX_SIZE)
            //重新计算偏移位置
            offset += ENCRYPT_MAX_SIZE
        } else {
            //加密最后一块
            temp = cipher.doFinal(byteArray, offset, byteArray.size - offset)
            //重新计算便宜位置
            offset = byteArray.size
        }
        //存储到临时缓存区
        bos.write(temp)
    }
    bos.close()

    return base64Encode(bos.toByteArray())
}

/**
 * 私钥解密
 * @param content 公钥生成的密文
 * @param privateKey 私钥
 * @return String
 */
fun decryptByPrivsteKey(content: String, privateKey: PrivateKey): String {

    val byteArray = base64Decode(content)

    //创建cipher
    val cipher = Cipher.getInstance(transformation)
    //初始化cipher
    cipher.init(Cipher.DECRYPT_MODE, privateKey)
    //加密解密  分段解密
    //val encrypt = cipher.doFinal(input.toByteArray())
    var temp: ByteArray? = null
    var offset = 0//当前偏移位置
    val bos = ByteArrayOutputStream()
    while (byteArray.size - offset > 0) {//没加密完
        //每次最大加密128个字节
        if (byteArray.size - offset >= DECRYPT_MAX_SIZE) {
            //剩余部分大于128
            //加密完整的128字节
            temp = cipher.doFinal(byteArray, offset, DECRYPT_MAX_SIZE)
            //重新计算偏移位置
            offset += DECRYPT_MAX_SIZE
        } else {
            //加密最后一块
            temp = cipher.doFinal(byteArray, offset, byteArray.size - offset)
            //重新计算便宜位置
            offset = byteArray.size
        }
        //存储到临时缓存区
        bos.write(temp)
    }
    bos.close()


    return String(bos.toByteArray())
}


/**
 * 公钥加密
 * @param content 需要加密的内容
 * @param publicKey 公钥
 * @return String
 */
fun encryptByPublicKey(content: String, publicKey: PublicKey): String {

    val byteArray = content.toByteArray()
    //创建cipher
    val cipher = Cipher.getInstance(transformation)
    //初始化cipher
    cipher.init(Cipher.ENCRYPT_MODE, publicKey)
    //加密解密  分段加密
    //val encrypt = cipher.doFinal(input.toByteArray())
    var temp: ByteArray? = null
    var offset = 0//当前偏移位置
    val bos = ByteArrayOutputStream()
    while (byteArray.size - offset > 0) {//没加密完
        //每次最大加密117个字节
        if (byteArray.size - offset >= ENCRYPT_MAX_SIZE) {
            //剩余部分大于117
            //加密完整的117字节
            temp = cipher.doFinal(byteArray, offset, ENCRYPT_MAX_SIZE)
            //重新计算偏移位置
            offset += ENCRYPT_MAX_SIZE
        } else {
            //加密最后一块
            temp = cipher.doFinal(byteArray, offset, byteArray.size - offset)
            //重新计算便宜位置
            offset = byteArray.size
        }
        //存储到临时缓存区
        bos.write(temp)
    }
    bos.close()


    return base64Encode(bos.toByteArray())
}

/**
 * 公钥解密
 * @param content 私钥生成的密文
 * @param publicKey 公钥
 * @return String
 */
fun decryptByPublicKey(content: String, publicKey: PublicKey): String {

    val byteArray = base64Decode(content)

    //创建cipher
    val cipher = Cipher.getInstance(transformation)
    //初始化cipher
    cipher.init(Cipher.DECRYPT_MODE, publicKey)
    //加密解密  分段解密
    //val encrypt = cipher.doFinal(input.toByteArray())
    var temp: ByteArray? = null
    var offset = 0//当前偏移位置
    val bos = ByteArrayOutputStream()
    while (byteArray.size - offset > 0) {//没加密完
        //每次最大加密128个字节
        if (byteArray.size - offset >= DECRYPT_MAX_SIZE) {
            //剩余部分大于128
            //加密完整的128字节
            temp = cipher.doFinal(byteArray, offset, DECRYPT_MAX_SIZE)
            //重新计算偏移位置
            offset += DECRYPT_MAX_SIZE
        } else {
            //加密最后一块
            temp = cipher.doFinal(byteArray, offset, byteArray.size - offset)
            //重新计算便宜位置
            offset = byteArray.size
        }
        //存储到临时缓存区
        bos.write(temp)
    }
    bos.close()


    return String(bos.toByteArray())
}